%%capture
import classify
import sentiment
import lime
from sklearn.pipeline import make_pipeline
import sklearn
import numpy as np
import random
from lime.lime_text import LimeTextExplainer
import eli5
import plot_confusion_matrix
from eli5.lime import TextExplainer
import pandas as pd
import matplotlib.pyplot as plt
import string
def scramble(sentence):
split = sentence.split() # Split the string into a list of words
random.shuffle(split) # This shuffles the list in-place.
return ' '.join(split) # Turn the list back into a string
unlabeled, sent, cls = sentiment.main()
vectorizer = sent.count_vect
c = make_pipeline(vectorizer, cls)
class_names = ['NEGATIVE', 'POSITIVE']
print("Number of features: " + str(len(cls.coef_[0])))
eli5.show_weights(cls,feature_names=sent.count_vect.get_feature_names(),target_names=class_names)
print("Result for an empty input:\n")
empty_pred = c.predict([""])[0]
print("Prediction: " + class_names[empty_pred])
print("Confidence: " + str(float(c.decision_function([""]))))
print("Probability: " + str(c.predict_proba([""])[0,empty_pred]))
plot_confusion_matrix.plot_confusion_matrix(sent.devy, cls.predict(sent.devX),classes=np.array(class_names))
fav_review = unlabeled.data[643]
print("My favorite review:")
print(fav_review + '\n')
pred = c.predict([fav_review])[0]
print("Prediction: " + class_names[pred])
print("Confidence: " + str(float(c.decision_function([fav_review]))))
print("Probability: " + str(c.predict_proba([fav_review])[0,pred]))
a = sent.count_vect.transform([fav_review]).T.toarray()
r1 = (np.array(sent.count_vect.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = cls.coef_[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
plt.bar(r1[max5],product[max5])
plt.title('Most Positive Features')
plt.show()
plt.bar(r1[min5],product[min5])
plt.title('Most Negative Features')
plt.show()
explainer = LimeTextExplainer(class_names=class_names,bow=False)
exp = explainer.explain_instance(fav_review, c.predict_proba, num_features=15)
exp.show_in_notebook(text=True)
scrambled = scramble(fav_review)
scrambled_exp = explainer.explain_instance(scrambled, c.predict_proba, num_features=15)
scrambled_exp.show_in_notebook(text=True)
top2words = (np.array(exp.as_list())[:2])[:,0]
top2words = top2words.tolist()
wo_most_impact1 = fav_review.replace(top2words[0],'').replace(top2words[1],'')
wo_exp = explainer.explain_instance(wo_most_impact1, c.predict_proba, num_features=15)
wo_exp.show_in_notebook(text=True)
oc_review = unlabeled.data[70204]
print("An overconfident review:")
print(oc_review + '\n')
oc_pred = c.predict([oc_review])[0]
print("Prediction: " + class_names[oc_pred])
print("Confidence: " + str(float(c.decision_function([oc_review]))))
print("Probability: " + str(c.predict_proba([oc_review])[0,oc_pred]))
a = sent.count_vect.transform([oc_review]).T.toarray()
r1 = (np.array(sent.count_vect.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = cls.coef_[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
plt.bar(r1[max5],product[max5])
plt.title('Most Positive Features')
plt.show()
plt.bar(r1[min5],product[min5])
plt.title('Most Negative Features')
plt.show()
oc_exp = explainer.explain_instance(oc_review, c.predict_proba, num_features=15)
oc_exp.show_in_notebook(text=True)
scrambled = scramble(oc_review)
scrambled_exp = explainer.explain_instance(scrambled, c.predict_proba, num_features=15)
scrambled_exp.show_in_notebook(text=True)
top2words = (np.array(oc_exp.as_list())[:2])[:,0]
top2words = top2words.tolist()
wo_most_impact2 = oc_review.replace(top2words[0],'').replace(top2words[1],'')
wo_exp2 = explainer.explain_instance(wo_most_impact2, c.predict_proba, num_features=15)
wo_exp2.show_in_notebook(text=True)
test_input = "The food at the restaurant was pretty good but the service was a terrible"
print("Test Input:")
print(test_input + '\n')
ti_pred = c.predict([test_input])[0]
print("Prediction: " + class_names[ti_pred])
print("Confidence: " + str(float(c.decision_function([test_input]))))
print("Probability: " + str(c.predict_proba([test_input])[0,ti_pred]))
a = sent.count_vect.transform([test_input]).T.toarray()
r1 = (np.array(sent.count_vect.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = cls.coef_[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
plt.bar(r1[max5],product[max5])
plt.title('Most Positive Features')
plt.show()
plt.bar(r1[min5],product[min5])
plt.title('Most Negative Features')
plt.show()
ti_exp = explainer.explain_instance(test_input, c.predict_proba, num_features=15)
ti_exp.show_in_notebook(text=True)
scrambled = scramble(test_input)
ti_scrambled_exp = explainer.explain_instance(scrambled, c.predict_proba, num_features=15)
ti_scrambled_exp.show_in_notebook(text=True)
top2words = (np.array(ti_exp.as_list())[:2])[:,0]
top2words = top2words.tolist()
wo_most_impact3 = test_input.replace(top2words[0],'').replace(top2words[1],'')
wo_exp3 = explainer.explain_instance(wo_most_impact3, c.predict_proba, num_features=15)
wo_exp3.show_in_notebook(text=True)
In recent years, there has been constant outrage over Twitter's banning of users who tweet inflammatory statements. There is a need to balance between creating a safe space for everyone and allowing freedom of speech to thrive on social media. A good hate speech detector is crucial for this. In this classication task, I use a TF-IDF vectorizer along with a multi-class logistic regression classifier to classify tweets as one of the three categories: hate speech, offensive language, or neither.
hate_speech = pd.read_csv('labeled_data.csv')
del hate_speech['index']
del hate_speech['count']
del hate_speech['hate_speech']
del hate_speech['offensive_language']
del hate_speech['neither']
hs_classes = ['hate speech', 'offensive language', 'neither']
msk = np.random.rand(len(hate_speech)) < 0.8
train = hate_speech[msk]
test = hate_speech[~msk]
hate_speech.head()
vec = sklearn.feature_extraction.text.TfidfVectorizer(ngram_range=(1,3))
clf2 = sklearn.linear_model.LogisticRegression(solver='lbfgs',multi_class='ovr',max_iter=200)
c1 = make_pipeline(vec,clf2)
c1.fit(train['tweet'],train['class'])
print("Number of features: " + str(len(clf2.coef_[0])))
print("Test Accuracy: ",c1.score(test['tweet'],test['class']),'\n')
plot_confusion_matrix.plot_confusion_matrix(test['class'], c1.predict(test['tweet']),classes=np.array(hs_classes))
eli5.show_weights(c1,feature_names=vec.get_feature_names(),target_names=hs_classes)
print("Result for an empty input:\n")
empty_pred = c1.predict([""])[0]
print("Prediction: " + hs_classes[empty_pred])
print("Probability: " + str(c1.predict_proba([""])[0,empty_pred]))
fav_instance = test['tweet'][5883]
print("My Favorite Instance:")
print(fav_instance + '\n')
fav_pred = c1.predict([fav_instance])[0]
print("Prediction: " + hs_classes[fav_pred])
print("True Label: " + hs_classes[test['class'][5883]])
print("Confidence: " + str(c1.predict_proba([fav_instance])[0,fav_pred]))
a = vec.transform([fav_instance]).T.toarray()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[0].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = hate speech')
plt.show()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[1].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = offensive language')
plt.show()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[2].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = neither')
plt.show()
hs_explainer = LimeTextExplainer(class_names=hs_classes,bow=False)
fav_exp = hs_explainer.explain_instance(fav_instance, c1.predict_proba, num_features=15)
fav_exp.show_in_notebook(text=True)
scrambled = scramble(fav_instance)
scrambled_exp = hs_explainer.explain_instance(scrambled, c1.predict_proba, num_features=15)
scrambled_exp.show_in_notebook(text=True)
top2words = (np.array(fav_exp.as_list())[:2])[:,0]
top2words = top2words.tolist()
wo_most_impact_hs = fav_instance.replace(top2words[0],'').replace(top2words[1],'')
wo_exp_hs = hs_explainer.explain_instance(wo_most_impact_hs, c1.predict_proba, num_features=15)
wo_exp_hs.show_in_notebook(text=True)
test_input2 = "I’ve been taught binary logistic regression using the sigmoid function, and multi-class logistic regression using a softmax."
print("Test Input:")
print(test_input2 + '\n')
ti_pred2 = c1.predict([test_input2])[0]
print("Prediction: " + hs_classes[ti_pred2])
print("Confidence: " + str(c1.predict_proba([test_input2])[0,ti_pred2]))
a = vec.transform([test_input2]).T.toarray()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[0].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = hate speech')
plt.show()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[1].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = offensive language')
plt.show()
r1 = (np.array(vec.get_feature_names()).T[(a != 0).reshape(-1,)])
r2 = (clf2.coef_[2].reshape(1,-1))[a.T != 0]
product = (r2 * (a[a != 0]))
min5 = product.argsort()[:5]
max5 = product.argsort()[-5:]
idx_hs = np.concatenate((min5,max5))
plt.bar(r1[idx_hs],product[idx_hs])
plt.title('Most Impactful Features for y = neither')
plt.show()
ti_exp2 = hs_explainer.explain_instance(test_input2, c1.predict_proba, num_features=15)
ti_exp2.show_in_notebook(text=True)
scrambled = scramble(test_input2)
scrambled_exp = hs_explainer.explain_instance(scrambled, c1.predict_proba, num_features=15)
scrambled_exp.show_in_notebook(text=True)
top2words = (np.array(ti_exp2.as_list())[:2])[:,0]
top2words = top2words.tolist()
wo_most_impact_hs2 = test_input2.replace(top2words[0],'').replace(top2words[1],'')
wo_exp_hs2 = hs_explainer.explain_instance(wo_most_impact_hs2, c1.predict_proba, num_features=15)
wo_exp_hs2.show_in_notebook(text=True)